home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 21
/
Cream of the Crop 21 (Terry Blount) (October 1996).iso
/
os2
/
e33el2.zip
/
emacs
/
19.33
/
lisp
/
ediff-diff.el
< prev
next >
Wrap
Lisp/Scheme
|
1996-07-02
|
44KB
|
1,196 lines
;;; ediff-diff.el --- diff-related utilities
;; Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc.
;; Author: Michael Kifer <kifer@cs.sunysb.edu>
;; This file is part of GNU Emacs.
;; GNU Emacs is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 2, or (at your option)
;; any later version.
;; GNU Emacs is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs; see the file COPYING. If not, write to the
;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
;;; Code:
(require 'ediff-init)
(defvar ediff-shell
(cond ((eq system-type 'emx) "cmd") ; OS/2
((memq system-type '(ms-dos windows-nt windows-95))
shell-file-name) ; no standard name on MS-DOS
((memq system-type '(vax-vms axp-vms)) "*dcl*") ; VMS
(t "sh")) ; UNIX
"*The shell used to run diff and patch. If user's .profile or
.cshrc files are set up correctly, any shell will do. However, some people
set $prompt or other things incorrectly, which leads to undesirable output
messages. These may cause Ediff to fail. In such a case, set ediff-shell
to a shell that you are not using or, better, fix your shell's startup file.")
(defvar ediff-diff-program "diff"
"*Program to use for generating the differential of the two files.")
(defvar ediff-diff-options ""
"*Options to pass to `ediff-diff-program'.
If diff\(1\) is used as `ediff-diff-program', then the most useful options are
`-w', to ignore space, and `-i', to ignore case of letters.
At present, the option `-c' is ignored, since Ediff doesn't understand this
type of output.")
(defvar ediff-custom-diff-program ediff-diff-program
"*Program to use for generating custom diff output for saving it in a file.
This output is not used by Ediff internally.")
(defvar ediff-custom-diff-options "-c"
"*Options to pass to `ediff-custom-diff-program'.")
;;; Support for diff3
(defvar ediff-match-diff3-line "^====\\(.?\\)$"
"Pattern to match lines produced by diff3 that describe differences.")
(defvar ediff-diff3-program "diff3"
"*Program to be used for three-way comparison.
Must produce output compatible with Unix's diff3 program.")
(defvar ediff-diff3-options ""
"*Options to pass to `ediff-diff3-program'.")
(defvar ediff-diff3-ok-lines-regexp
"^\\([1-3]:\\|====\\| \\|.*Warning *:\\|.*No newline\\|.*missing newline\\|^\C-m$\\)"
"*Regexp that matches normal output lines from `ediff-diff3-program'.
Lines that do not match are assumed to be error messages.")
;; keeps the status of the current diff in 3-way jobs.
;; the status can be =diff(A), =diff(B), or =diff(A+B)
(ediff-defvar-local ediff-diff-status "" "")
;;; Fine differences
(ediff-defvar-local ediff-auto-refine (if (ediff-has-face-support-p) 'on 'nix)
"If `on', Ediff auto-highlights fine diffs for the current diff region.
If `off', auto-highlighting is not used. If `nix', no fine diffs are shown
at all, unless the user force-refines the region by hitting `*'.
This variable can be set either in .emacs or toggled interactively.
Use `setq-default' if setting it in .emacs")
(ediff-defvar-local ediff-ignore-similar-regions nil
"*If t, skip over difference regions that differ only in the white space and line breaks.
This variable can be set either in .emacs or toggled interactively.
Use `setq-default' if setting it in .emacs")
(ediff-defvar-local ediff-auto-refine-limit 1400
"*Auto-refine only the regions of this size \(in bytes\) or less.")
;;; General
(defvar ediff-diff-ok-lines-regexp
"^\\([0-9,]+[acd][0-9,]+$\\|[<>] \\|---\\|.*Warning *:\\|.*No +newline\\|.*missing +newline\\|^\C-m$\\)"
"Regexp that matches normal output lines from `ediff-diff-program'.
This is mostly lifted from Emerge, except that Ediff also considers
warnings and `Missing newline'-type messages to be normal output.
Lines that do not match are assumed to be error messages.")
(defvar ediff-match-diff-line (let ((x "\\([0-9]+\\)\\(\\|,\\([0-9]+\\)\\)"))
(concat "^" x "\\([acd]\\)" x "$"))
"Pattern to match lines produced by diff that describe differences.")
(ediff-defvar-local ediff-setup-diff-regions-function nil
"value is a function symbol depending on the kind of job is to be done.
For 2-way jobs and for ediff-merge, it should be `ediff-setup-diff-regions'.
For jobs requiring diff3, it should be `ediff-setup-diff-regions3'.
The function should take three mandatory arguments, file-A, file-B, and
file-C. It may ignore file C for diff2 jobs. It should also take
one optional arguments, diff-number to refine.")
;;; Functions
;; Generate the difference vector and overlays for the two files
;; With optional arg REG-TO-REFINE, refine this region.
;; File-C argument is not used here. It is there just because
;; ediff-setup-diff-regions is called via a funcall to
;; ediff-setup-diff-regions-function, which can also have the value
;; ediff-setup-diff-regions3, which takes 4 arguments.
(defun ediff-setup-diff-regions (file-A file-B file-C)
;;; ;; Force all minibuffers to display ediff's messages.
;;; ;; When xemacs implements minibufferless frames, this won't be necessary
;;; (if ediff-xemacs-p (setq synchronize-minibuffers t))
;; create, if it doesn't exist
(or (ediff-buffer-live-p ediff-diff-buffer)
(setq ediff-diff-buffer
(get-buffer-create (ediff-unique-buffer-name "*ediff-diff" "*"))))
(ediff-make-diff2-buffer ediff-diff-buffer file-A file-B)
(ediff-prepare-error-list ediff-diff-ok-lines-regexp ediff-diff-buffer)
(ediff-convert-diffs-to-overlays
(ediff-extract-diffs
ediff-diff-buffer ediff-word-mode ediff-narrow-bounds)))
;; Run the diff program on FILE1 and FILE2 and put the output in DIFF-BUFFER
;; Return the size of DIFF-BUFFER
(defun ediff-make-diff2-buffer (diff-buffer file1 file2)
(cond ((< (ediff-file-size file1) 0)
(message "Can't diff remote files: %s"
(ediff-abbreviate-file-name file1))
(sit-for 2)
;; 1 is an error exit code
1)
((< (ediff-file-size file2) 0)
(message "Can't diff remote file: %s"
(ediff-abbreviate-file-name file2))
(sit-for 2)
(message "")
;; 1 is an error exit code
1)
(t (message "Computing differences between %s and %s ..."
(file-name-nondirectory file1)
(file-name-nondirectory file2))
;; this erases the diff buffer automatically
(ediff-exec-process ediff-diff-program
diff-buffer
'synchronize
ediff-diff-options file1 file2)
;;(message "Computing differences ... done")
(message "")
(ediff-eval-in-buffer diff-buffer
(buffer-size)))))
;; If file-A/B/C is nil, do 2-way comparison with the non-nil buffers
;; This function works for diff3 and diff2 jobs
(defun ediff-setup-fine-diff-regions (file-A file-B file-C reg-num)
(or (ediff-buffer-live-p ediff-fine-diff-buffer)
(setq ediff-fine-diff-buffer
(get-buffer-create
(ediff-unique-buffer-name "*ediff-fine-diff" "*"))))
(let (diff3-job diff-program diff-options ok-regexp diff-list)
(setq diff3-job ediff-3way-job
diff-program (if diff3-job ediff-diff3-program ediff-diff-program)
diff-options (if diff3-job ediff-diff3-options ediff-diff-options)
ok-regexp (if diff3-job
ediff-diff3-ok-lines-regexp
ediff-diff-ok-lines-regexp))
(ediff-message-if-verbose "Refining difference region %d ..." (1+ reg-num))
(ediff-exec-process diff-program ediff-fine-diff-buffer 'synchronize
diff-options
;; The shuffle below is because we can compare 3-way
;; or in several 2-way fashions, like fA fC, fA fB,
;; or fB fC.
(if file-A file-A file-B)
(if file-B file-B fi